package com.redwine.app.net.responses;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.redwine.app.net.GsonRequest;
import com.redwine.app.utils.LogUtil;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import internal.org.apache.http.entity.mime.MultipartEntity;
import internal.org.apache.http.entity.mime.content.FileBody;
import internal.org.apache.http.entity.mime.content.StringBody;

public class MultipartRequest<T> extends Request<T> {

    private final Gson gson = new Gson();

    private final Class<T> clazz;

    private MultipartEntity entity = new MultipartEntity();

    private final Response.Listener<T> mListener;

    private List<File> mFileParts;
    private String mFilePartName;
    private Map<String, String> params3 = null;
    private Map<String, String> mParams;

    /**
     * 多个文件，对应一个key
     *
     * @param url
     * @param errorListener
     * @param clazz
     * @param listener
     * @param filePartName
     * @param files
     * @param params2
     */
    public MultipartRequest(String url, Class<T> clazz, String filePartName,
                            List<File> files, Map<String, String> params2, Response.Listener<T> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.clazz = clazz;
        mFilePartName = filePartName;
        mListener = listener;
        mFileParts = files;
        this.mParams = GsonRequest.getCommonMap();

        if (params2 != null) {
            params3 = params2;
            this.mParams.putAll(params2);
        }

        LogUtil.e("params", "params" + this.mParams.toString());
        buildMultipartEntity();
    }

    private void buildMultipartEntity() {
        if (mFileParts != null && mFileParts.size() > 0) {
            for (int i = 0; i < mFileParts.size(); i++) {
                entity.addPart(mFilePartName + i, new FileBody(mFileParts.get(i)));
            }
            long l = entity.getContentLength();
            LogUtil.e("params", mFileParts.size() + "个，长度：" + l);
        }

        try {
            if (mParams != null && mParams.size() > 0) {
                for (Map.Entry<String, String> entry : mParams.entrySet()) {
                    entity.addPart(
                            entry.getKey(),
                            new StringBody(entry.getValue(), Charset
                                    .forName("UTF-8")));
                }
            }
        } catch (UnsupportedEncodingException e) {
            LogUtil.e("params", "UnsupportedEncodingException");
        }
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            entity.writeTo(bos);
        } catch (IOException e) {
            LogUtil.e("params", "IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }

        LogUtil.e("params", "result===" + parsed.toString());

        T fromJson = gson.fromJson(parsed, clazz);
        return Response
                .success(fromJson, HttpHeaderParser.parseCacheHeaders(response));
    }


    @Override
    protected void deliverResponse(T response) {
        mListener.onResponse(response);
    }


    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();
        if (headers == null || headers.equals(Collections.emptyMap())) {
            headers = new HashMap<String, String>();
        }
        return headers;
    }

    @Override
    public String getBodyContentType() {
        return entity.getContentType().getValue();
    }
}